Saving Data to Files

 

Steven Cen

 

Introduction

 

This tutorial will teach you how to get data to persist when you close the app and such. For example, for a game, you may want to save the highest score in a file, or for a drawing app, you may want to save pictures the user draws.

 

The two ways to store data with persistence that are discussed in this tutorial are onto the internal storage and external storage. However, there are other methods including saving primitive data with SharedPreferences and managing more complex data with MySQL but they won’t be taught here.

 

Internal Storage

 

Each application on your device has its own private directory which only it has access to (unless you specify otherwise). Internal storage is always available for access, and when you uninstall the app, the app’s data in the internal storage is also deleted.  

 

Create a new project with MainActivity.java and activity_main.xml as the layout file.

In activity_main.xml, add the following code.

 

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

  android:orientation="vertical"

  android:layout_width="fill_parent"

  android:layout_height="fill_parent">

 

  <TextView

      android:textSize="30dp"

      android:layout_margin="20dp"

      android:layout_width="fill_parent"

      android:layout_height="wrap_content"

      android:text="ENTER TEXT"

      android:gravity="center"/>

 

  <EditText

      android:id="@+id/textbox"

      android:gravity="top"

      android:layout_width="fill_parent"

      android:layout_height="wrap_content"

      android:layout_marginBottom="20dp"/>

 

  <Button android:id="@+id/write_internal"

      android:layout_width="fill_parent"

      android:layout_height="wrap_content"

      android:text="Write to Internal Storage"

      android:onClick="writeToInternal" />

 

  <Button android:id="@+id/read_internal"

      android:layout_width="fill_parent"

      android:layout_height="wrap_content"

      android:text="Read the Internal Storage"

      android:onClick="readInternal"/>

 

  <TextView

      android:id="@+id/display_text"

      android:layout_width="match_parent"

      android:layout_height="wrap_content"

      android:textSize="16sp"

      android:layout_margin="20dp"/>

</LinearLayout>

 

Your layout should look something like this:

 

https://lh6.googleusercontent.com/PhOp6x-usooLmd6pUh7o2AsFV42P8PaU72qQKbcAx7vVUyQLz6fgp5SSbyPdIgiKjZnvIyCyurmGy3lZXoXayCrkmoUUvPYil1DJOn9ZhKMmBk-K30ZaqY-ROpjUHYO6aE2lmU4f

 

In your MainActivity class, define the following variables/handles and change onCreate to this:

 

final String FILE_NAME = "nameMeWhatYouWant.txt";//name of the file to write/save data to

TextView displayText;

EditText textBoxEdit;

 

@Override

public void onCreate(Bundle savedInstanceState) {

  super.onCreate(savedInstanceState);

  setContentView(R.layout.activity_main);

 

  displayText = (TextView) findViewById(R.id.display_text);

  textBoxEdit = (EditText) findViewById(R.id.textbox);

 

}

 

The two buttons in your layout file have android:onClick properties, so implement them like so:

 

// Write to the file by taking the text from your EditText

public void writeToInternal(View v) {

  try {

      OutputStreamWriter out = new OutputStreamWriter(openFileOutput(FILE_NAME, Context.MODE_PRIVATE)); // Context.MODE_PRIVATE denotes that this file to write to is accessible only by the application itself, stored in some designated directory in your device’s internal storage

      out.write(textBoxEdit.getText().toString());

      out.close();

 

      Toast.makeText(this, "Successfully wrote to " + FILE_NAME, Toast.LENGTH_LONG).show();

  } catch (Exception e) {

      e.printStackTrace();

  }

}

 

//Read from the file and spit it out onto the TextView

public void readInternal  (View v) {

  try {

      InputStream inputStream = openFileInput(FILE_NAME);

 

      if (inputStream != null) { // make sure file exists/is openable

          InputStreamReader inputStreamReader = new InputStreamReader(inputStream);

          BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

          String str;

          StringBuilder strBuf = new StringBuilder();

 

          while ((str = bufferedReader.readLine()) != null) {

              strBuf.append(str + "\n"); // append the new line that you read

          }

 

          inputStream.close();

          displayText.setText(strBuf.toString());

      }

  } catch (java.io.FileNotFoundException e) {

      //If you haven't created the file, you can't read from it. Thus you should get this error if so.

 

  } catch (Exception e) {

      e.printStackTrace();

  }

 

}

 

External Storage

 

Files saved onto external storage are accessible by any application and are not deleted when you delete the application which saved that file. When you connect your device to your computer and mount your phone as a USB storage device, you will get to browse the external storage of your device on your computer. Other external storage devices include SD cards. But your phone might not have an SD card, so it will emulate one.

 

To access the external storage, the application needs special permission. So go to your manifest and put the following xml tag into the file as a direct child of <manifest>

 

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

 

Now change your layout code to the following:

 

<ScrollView

  android:layout_height="fill_parent"

  android:layout_width="fill_parent"

  xmlns:android="http://schemas.android.com/apk/res/android">

  <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

      android:orientation="vertical"

      android:layout_width="fill_parent"

      android:layout_height="fill_parent">

 

      <TextView

          android:textSize="30dp"

          android:layout_margin="20dp"

          android:layout_width="fill_parent"

          android:layout_height="wrap_content"

          android:text="ENTER TEXT"

          android:gravity="center"/>

 

      <EditText

          android:id="@+id/textbox"

          android:gravity="top"

          android:layout_width="fill_parent"

          android:layout_height="wrap_content"

          android:layout_marginBottom="20dp"/>

 

      <Button android:id="@+id/write_internal"

          android:layout_width="fill_parent"

          android:layout_height="wrap_content"

          android:text="Write to Internal Storage"

          android:onClick="writeToInternal" />

 

      <Button android:id="@+id/read_internal"

          android:layout_width="fill_parent"

          android:layout_height="wrap_content"

          android:text="Read the Internal Storage"

          android:onClick="readInternal"/>

 

      <Button

          android:id="@+id/write_external"

          android:layout_width="match_parent"

          android:layout_height="wrap_content"

          android:text="Write to External Storage"

          android:layout_marginTop="30dp"/>

      <Button

          android:id="@+id/read_external"

          android:layout_width="match_parent"

          android:layout_height="wrap_content"

          android:text="Read the External Storage" />

 

      <TextView

          android:id="@+id/display_text"

          android:layout_width="match_parent"

          android:layout_height="wrap_content"

          android:textSize="16sp"

          android:layout_margin="20dp"/>



  </LinearLayout>

</ScrollView>

 

Your screen should now look something like this:

https://lh6.googleusercontent.com/tF0qWzBz0uW9EMyEzHBovOuZPGSCcgAdviTO1cLU-LRf6XQQ3P9kB7fN_j63Wbi0uE7W8GdtvpZVPQal5IhOuBybwU9UoFYQU2iCJmO0cZW691QEg8oZBNaavcNmBBYih34HkDqh

 

Add the following variables definitions to the class:

 

// The directory for your device’s external storage

final String externalStorage = Environment.getExternalStorageDirectory().getPath();

 

// Name of the folder you are going to create in the external storage

String folderName = "WowIHaveMyOwnFolder";

 

// A folder is a file too, and you need to make the directory with code later

File folder = new File(externalStorage, folderName);

 

Implement the onClick button functions with the following:

 

public void writeToExternal(View v) {

  //Create new folder called WowIHaveMyOwnFolder

  if (!folder.exists()) { // if folder doesn't exist

      boolean xx = folder.mkdirs();//”make a directory” that uses the file’s name that you declared earlier

      Toast.makeText(this, String.valueOf(xx), Toast.LENGTH_SHORT).show();

  }

 

  try {

      File myFile = new File(externalStorage+"/"+folderName, FILE_NAME+".txt");

      myFile.createNewFile();

      FileOutputStream fileOutputStream = new

 

      FileOutputStream(myFile);

      OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream);

 

      //Write to file

      outputStreamWriter.append(textBoxEdit.getText().toString());

 

      outputStreamWriter.close();

      fileOutputStream.close();

 

      Toast.makeText(getApplicationContext(), FILE_NAME + " saved.",Toast.LENGTH_LONG).show();

 

  } catch (FileNotFoundException e) {

      e.printStackTrace();

  }

  catch (IOException e) {

      e.printStackTrace();

  }

 

}

 

public void readExternal(View v) {

  String line = "";

  StringBuilder stringBuilder = new StringBuilder();

  try {

      File myFile = new File(externalStorage+"/"+folderName, FILE_NAME+".txt");

 

      FileInputStream fileInputStream = new FileInputStream(myFile);

      BufferedReader myReader = new BufferedReader(new InputStreamReader(fileInputStream));

 

      while ((line = myReader.readLine()) != null) {

          stringBuilder.append(line + "\n");

      }

      myReader.close();

 

  } catch (Exception e) {

      e.printStackTrace();

  }

 

  displayText.setText(stringBuilder.toString());

}

 

Although we are writing to external storage with the same FILE_NAME for the name of the file we are saving, keep in mind that the internal and external files are completely unrelated and just share the same name for convenience in this tutorial.

 

If you read and write to a file, you should get something like the following:

https://lh4.googleusercontent.com/Iz_3o1iFHjL5XBR6V0WsjgOpgRfvlbJWcArz9hGntyyI1FsPz3f66oiJ3WMB-AtHnYYieve-2tsJ1wS4Yy94mH1HmjabTcQ_UQJZM8FwrQnzYvKpURPpu3W2rLYPyrtc63Wl_flL

 

If you write to external storage and you plug your phone into your computer as a media device, you can view the external storage directories and you should see the folder made with the file you made in it!

 

https://lh6.googleusercontent.com/rJevjvIRJFCJb4qaH-DPpKRymXPxviw3IdVuz_7YnmeId8RZlillHFRg2PlcesxXGm78h3oNJc1AaAScstSRfzb1bZkXLrnNJ0XbpZEbYLAbMy_gktSlslkz7zvUdrwIPt7fF9pyhttps://lh4.googleusercontent.com/hBB1hzVLmf3hbZZd9uYdQe-Jc0RT545VYT_J2r05JuHG9rOwL3QhJbeAYAADw7c3jR0EJbHeFpnmJKtuEkadWKb9E1JXxf6wm1UrHgKXyY8PLyPleUtGguSOom_pOH0dOf9ka_Ln